package com.zcxy.mybatis.util;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zcxy.exception.BusinessException;
import com.zcxy.mybatis.util.bean.Relation;
import com.zcxy.mybatis.util.enums.FieldCollectionType;
import com.zcxy.mybatis.util.enums.RelationType;
import com.zcxy.mybatis.util.mapper.AutoMapper;
import com.zcxy.util.SpringContextHolder;
import org.springframework.util.Assert;

import java.lang.reflect.Field;
import java.util.List;
import java.util.Set;

/**
 * @author zcc 860474958@qq.com
 * @version 1.0.0
 * @ClassName RelationHelper.java
 * @Description TODO
 * @createTime 2020年05月27日 15:43:00
 */
public class RelationHelper {


    public static <T> T render(T t) {
        return RelationHelper.render(t, null);
    }

    public static <T> T render(T t, QueryWrapper... queryWrapper) {
        if (t == null) return t;
        Assert.state(!((t instanceof java.util.List) || (t instanceof java.util.Set)), "对象为集合请使用renderList方法");

        AutoMapper autoMapper = SpringContextHolder.getBean(AutoMapper.class);
        if (CollectionUtil.isEmpty(autoMapper.getR1())) {
            autoMapper.initData(autoMapper.getI1());
        }
        if (CollectionUtil.isEmpty(autoMapper.getR1())) {
            return t;
        }
        List<Relation> relations = autoMapper.getR1().get(t.getClass().getSimpleName());
        relations.stream().forEach(i -> {
            if (i.getRelationType() == RelationType.ONETOONE) {
                autoMapper.oneToOne(t, i, queryWrapper);
            } else if (i.getRelationType() == RelationType.ONETOMANY) {
                autoMapper.oneToMany(t, i, queryWrapper);
            } else if (i.getRelationType() == RelationType.MANYTOONE) {
                autoMapper.ManyToOne(t, i, queryWrapper);
            } else if (i.getRelationType() == RelationType.MANYTOMANY) {
                autoMapper.manyToMany(t, i, queryWrapper);
            }
        });
        return t;
    }


    public static <T> List<T> renderList(List<T> t) {
        return RelationHelper.renderList(t, null);
    }

    public static <T> List<T> renderList(List<T> t, QueryWrapper... queryWrapper) {
        return RelationHelper.renderList(t, false, queryWrapper);
    }


    public static <T> List<T> renderList(List<T> t, boolean isleftjion, QueryWrapper... queryWrapper) {
        if (CollectionUtil.isEmpty(t)) return t;
        AutoMapper autoMapper = SpringContextHolder.getBean(AutoMapper.class);
        if (CollectionUtil.isEmpty(autoMapper.getR1())) {
            autoMapper.initData(autoMapper.getI1());
        }
        if (CollectionUtil.isEmpty(autoMapper.getR1()) || CollectionUtil.isEmpty(t)) {
            return t;
        }
        /* autoMapper.initData(autoMapper.getEntityPackages());*/
        List<Relation> relations = autoMapper.getR1().get(t.get(0).getClass().getSimpleName());
        if (relations == null) throw new BusinessException("找不到" + t.get(0).getClass().getSimpleName() + "bean配置关系");
        relations.stream().forEach(i -> {
            if (i.getRelationType() == RelationType.ONETOONE) {
                autoMapper.oneToOne(t, i, queryWrapper);
            } else if (i.getRelationType() == RelationType.ONETOMANY) {
                autoMapper.oneToMany(t, i, queryWrapper);
            } else if (i.getRelationType() == RelationType.MANYTOONE) {
                autoMapper.ManyToOne(t, i, queryWrapper);
            } else if (i.getRelationType() == RelationType.MANYTOMANY) {
                autoMapper.manyToMany(t, i, queryWrapper);
            }

        });
        //启用leftjoin
        if (isleftjion) {
            for (int i = 0; i < relations.size(); i++) {
                Relation r = relations.get(i);
                Field $_6 = null;
                for (int k = 0; k < t.size(); k++) {
                    try {
                        $_6 = t.get(0).getClass().getDeclaredField(r.getFiledName());
                        $_6.setAccessible(true);
                        // list to set
                        if (r.getFieldCollectionType() == FieldCollectionType.SET) {
                            if (CollectionUtil.isEmpty((Set) $_6.get(t.get(k)))) {
                                t.remove(k);
                            }

                        } else if (r.getFieldCollectionType() == FieldCollectionType.LIST) {
                            if (CollectionUtil.isEmpty((List) $_6.get(t.get(k)))) {
                                t.remove(k);
                            }
                        } else {
                            if ($_6.get(t.get(k)) == null) {
                                t.remove(k);
                            }
                        }
                        $_6.setAccessible(false);
                    } catch (Exception e2) {
                        throw new RuntimeException(
                                String.format("{0} call setter {1} is not correct!", r, $_6.getName()));
                    }
                }
            }
        }
        return t;
    }

}
